from .Element.Base import *
from .Element.Header import *
from .Element.Version import *
from .Element.ControlFunction import *
from .Element.FunctionCommand import *
from .Element.FunctionStatus import *
from .Element.VehicleDescriptor import *
from .Element.AppFlag import *
from .Element.Error import *
from .HighLighter import *


class CAcpMsg(CItem):
    _gName = "ACP message"
    _gAppId = 0
    _gMsgType = 0

    def __init__(self,name=_gName):
        super(CAcpMsg, self).__init__(name)
        self._successor = 0
        self._func = CONTROL_FUNCTION_NONE

    def SetSuccessor(self, successor):
        self._successor=successor

    #base acp message only init application header and version element
    def InitElement(self):
        element = CAppHeader()
        element.SetHighLighter(self._highLighter)
        self.AddSubItem(element)

        element = CVersionElement()
        element.SetHighLighter(self._highLighter)
        self.AddSubItem(element)

    def ParseElement(self, dataStr):
        for name in self._nameList:
            element = self._subList[name]
            element.Parse(dataStr)

    #this is used to parse element exclude application header
    #parse acp message
    def Parse(self, dataStr):
        self._rawStr = DATA_STRING_FORMAT.format(dataStr.GetRawString())

        appHeader = CAppHeader()

        appHeader.Parse(dataStr)

        appId = appHeader.GetAppId()
        msgType = appHeader.GetMsgType()

        if appId == 0 | msgType == 0:
            self._errStr = "Invalid ACP message"
            return self

        #reset the data string,so it would restart parse from begin
        dataStr.Reset()


        if (appId == self._gAppId) and (msgType == self._gMsgType):
            self.InitElement()
            self.ParseElement(dataStr)
            return self
        else:
            if self._successor!=0:
                return self._successor.Parse(dataStr)



class CRvfcMsg(CAcpMsg):
    _gName = "RVFC message"
    _gAppId = 6
    _gMsgType = 2
    def __init__(self, name=_gName):
        super(CRvfcMsg, self).__init__(name)

    def InitElement(self):
        #the base init application header and version
        super(CRvfcMsg, self).InitElement()

        element = CControlFunctionElement()
        element.SetHighLighter(self._highLighter)
        self.AddSubItem(element)

        element = CFunctionCommandElement()
        element.SetHighLighter(self._highLighter)
        self.AddSubItem(element)

        element = CVehicleDescriptorElement()
        element.SetHighLighter(self._highLighter)
        self.AddSubItem(element)

    #RVFC should implement this function as it would set function
    def ParseElement(self, dataStr):
        for name in self._nameList:
            element = self._subList[name]
            if isinstance(element, CFunctionCommandElement):
                element.SetFunction(self._func)
            element.Parse(dataStr)
            if isinstance(element, CControlFunctionElement):
                self._func = element.GetFunction()



class CRvfsMsg(CAcpMsg):
    _gName = "RVFS message"
    _gAppId = 6
    _gMsgType = 3
    def __init__(self, name=_gName):
        super(CRvfsMsg, self).__init__(name)

    def InitElement(self):
        #the base init application header and version
        super(CRvfsMsg, self).InitElement()

        element = CControlFunctionElement()
        element.SetHighLighter(self._highLighter)
        self.AddSubItem(element)

        element = CFunctionStatusElement()
        element.SetHighLighter(self._highLighter)
        self.AddSubItem(element)

        element = CErrorElement()
        element.SetHighLighter(self._highLighter)
        self.AddSubItem(element)

        element = CVehicleDescriptorElement()
        element.SetHighLighter(self._highLighter)
        self.AddSubItem(element)

    #RVFS should implement this function as it would set function
    def ParseElement(self, dataStr):
        for name in self._nameList:
            element = self._subList[name]
            if isinstance(element, CFunctionStatusElement):
                element.SetFunction(self._func)
            element.Parse(dataStr)
            if isinstance(element, CControlFunctionElement):
                self._func = element.GetFunction()

class CProvUpdateMsg(CAcpMsg):
    _gName = "Provision Update message"
    _gAppId = 1
    _gMsgType = 1

    def __init__(self, name=_gName):
        super(CProvUpdateMsg, self).__init__(name)

    def InitElement(self):
        #the base init application header and version
        super(CProvUpdateMsg, self).InitElement()

        element = CAppFlagElement()
        element.SetHighLighter(self._highLighter)
        self.AddSubItem(element)

        element = CVehicleDescriptorElement()
        element.SetHighLighter(self._highLighter)
        self.AddSubItem(element)

class CProvReplyMsg(CAcpMsg):
    _gName = "Provision Reply message"
    _gAppId = 1
    _gMsgType = 3

    def __init__(self, name=_gName):
        super(CProvReplyMsg, self).__init__(name)

    def InitElement(self):
        #the base init application header and version
        super(CProvReplyMsg, self).InitElement()

        #this is the app flag
        element = CAppFlagElement()
        element.SetHighLighter(self._highLighter)
        self.AddSubItem(element)

        #this is the app status flag
        element = CStaFlagElement()
        element.SetHighLighter(self._highLighter)
        self.AddSubItem(element)

        element = CErrorElement()
        element.SetHighLighter(self._highLighter)
        self.AddSubItem(element)

        element = CVehicleDescriptorElement()
        element.SetHighLighter(self._highLighter)
        self.AddSubItem(element)

